package com.qf.fmall2302.config;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qf.fmall2302.user.entity.Users;
import com.qf.fmall2302.user.service.IUsersService;
import com.qf.fmall2302.utils.FmallConstants;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ShiroConfig {

    @Autowired
    IUsersService usersService;

    @Bean
    public Realm realm(){

        AuthorizingRealm authorizingRealm = new AuthorizingRealm() {
            @Override
            protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

                //1. 获取登录表单中传递的用户名
                String username = (String) token.getPrincipal();

                //2. 根据用户名查询数据库中的用户信息
                Users dbuser = usersService.getOne(new QueryWrapper<Users>().eq("username", username));

                SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(dbuser, dbuser.getPassword(),
                        ByteSource.Util.bytes(dbuser.getSalt()), this.getName());

                return simpleAuthenticationInfo;
            }

            @Override
            protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
                return null;
            }

        };

        // 设置该realm使用 Hash密码比对器
        authorizingRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return authorizingRealm;

    }


    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){

        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();

        matcher.setHashAlgorithmName("md5");
        matcher.setHashIterations(FmallConstants.HASH_TIMES);

        return matcher;

    }

    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
        /**
         * 让登录接口直接被shiro的过滤器放行
         * 第一个参数：接口的路径
         * 第二个参数：过滤器的名字，anon代表无需登录即可访问的特殊的过滤器
         */
        chainDefinition.addPathDefinition("/user/login", "anon");
        chainDefinition.addPathDefinition("/user/regist", "anon");
        chainDefinition.addPathDefinition("/swagger-ui.html", "anon");
        //放行springboot的错误页面请求url
        chainDefinition.addPathDefinition("/error", "anon");

//        chainDefinition.addPathDefinition("/**", "authc");

        // 让/index/indeximg由自定义的shiro filter 进行处理， "jwt" 这个值是 IOC容器中filter的名字
        chainDefinition.addPathDefinition("/index/indeximg", "jwt");

        return chainDefinition;
    }

}
